package com.freeman.cement.service.impl;

import com.freeman.cement.entity.ResponseResult;
import com.freeman.cement.exception.AppException;
import com.freeman.cement.exception.AppExceptionCodeMsg;
import com.freeman.cement.mapper.SmsDao;
import com.freeman.cement.entity.Sms;
import com.freeman.cement.service.SmsService;
import com.freeman.cement.util.ConfigUtil;
import com.freeman.cement.util.HttpClientUtil;
import com.freeman.cement.util.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;

@Service
public class SmsServiceImpl implements SmsService {

    private static Logger logger = LoggerFactory.getLogger(SmsServiceImpl.class);

    /**
     * 短信发送队列，阻塞队列
     */
    ArrayBlockingQueue<Sms> smsSendQueue;

    /**
     * 短信发送队列长度
     */
    private final int lengthOfSmsSendQueue = 300;

    @Resource
    private SmsDao smsDao;

    /**
     * 短信发送线程状态
     */
    private boolean isSendThreadRunning = false;

    /**
     * 短信发送服务网址
     */
    private String sendSmsMassWithCheckUrl = null;

    public SmsServiceImpl(){
        loadConfig();
        if(StringUtils.isNotBlank(sendSmsMassWithCheckUrl)){
            startSendThread();
        }
    }

    /**
     * 读取配置文件
     */
    private void loadConfig(){
        try {
            sendSmsMassWithCheckUrl = ConfigUtil.readKey("SendSmsMassWithCheckUrl");
        } catch (IOException e) {
            e.printStackTrace();
            sendSmsMassWithCheckUrl = null;
        }
    }

    /**
     * 启动短信发送线程
     */
    private void startSendThread(){
        try{
            smsSendQueue = new ArrayBlockingQueue<Sms>(lengthOfSmsSendQueue);
            new Thread(new SendThread()).start();
            isSendThreadRunning = true;
        } catch (Exception e){
            logger.error("startSendThread--->" + "初始化错误:" + e.getMessage());
            isSendThreadRunning = false;
        }
    }

    /**
     * 短信发送线程
     */
    public class SendThread implements Runnable{

        @Override
        public void run() {
            while (true){
                try{
                    Sms sms = smsSendQueue.take();
                    if(sms != null && smsDao != null){
                        //发送短信
                        Map<String, String> map = new HashMap<>();
                        map.put("phoneNumList", sms.getRecvPhoneList());
                        map.put("content", sms.getContent());
                        String senderId = "0";
                        if(sms.getSender() != null){
                            senderId = Integer.toString(sms.getSender());
                        }
                        map.put("senderId", senderId);
                        map.put("senderName", sms.getSenderName());
                        String rslt = HttpClientUtil.doGet(sendSmsMassWithCheckUrl, map, 1000, 1000);
                        if(StringUtils.isBlank(rslt)){
                            rslt = "failed";
                        }
                        //发送结果存入数据库
                        sms.setResult(rslt);
                        sms.setSendTime(new Date());
                        addSms(sms);
                    }
                } catch (InterruptedException e) {
                    System.out.println("SmsSendThread error:" + e.getMessage());
                }
                //发送一次短信后延时一次
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    System.out.println("SmsSendThread sleep error:" + e);
                }
            }
        }
    }

    /**
     * 发送短信
     * @param sms
     */
    @Override
    public void sendSms(Sms sms){
        if(isSendThreadRunning) {
            try {
                smsSendQueue.put(sms);
            } catch (InterruptedException e) {
                System.out.println("smsSendQueue put sms error:" + e.getMessage());
            }
        }
    }

    @Override
    public ResponseResult selectSmsByEventId(String eventId, int pageNo, int pageSize) {
        //验证分页范围
        if (pageNo < 1 || pageSize > 1000) {
            throw new AppException(AppExceptionCodeMsg.PAGE_NO_OR_SIZE_WRONG);
        }
        PageHelper.startPage(pageNo, pageSize, true);
        List<Sms> list = smsDao.selectSmsByEventId(eventId);
        PageInfo<Sms> pageInfo = new PageInfo<Sms>(list);
        return ResponseResult.success(pageInfo);
    }

    @Override
    public void addSms(Sms sms) {
        if(sms != null) {
            if(!(smsDao.addSms(sms) > 0)){
                logger.error("addSms--->" + "[sms]插入数据失败:" + sms.toString());
            }
        }
    }
}
